package com.v0710.module.oss.service.impl;


import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.v0710.framework.exception.ServiceException;
import com.v0710.framework.spring.SpringUtils;
import com.v0710.module.admin.entity.SysDictData;
import com.v0710.module.admin.entity.SysOss;
import com.v0710.module.admin.service.ISysDictDataService;
import com.v0710.module.admin.service.ISysOssService;
import com.v0710.module.oss.service.IFileService;

import com.v0710.module.oss.service.handler.FileStorageHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author 程序员Mars
 */
@Service
@Slf4j
@AllArgsConstructor
public class IFileServiceImpl implements IFileService {

    private final ISysOssService sysOssService;
    private final ISysDictDataService sysDictDataService;

    @Override
    public String uploadImg(MultipartFile file) {
        SysOss ossConfig = getOssConfig();
        List<SysDictData> sysOssType = sysDictDataService.getDictData("sys_oss_type");
        List<String> types = sysOssType.stream().map(SysDictData::getDictValue).collect(Collectors.toList());
        String storageType = ossConfig.getStorageType();
        if (!types.contains(storageType)) {
            throw new ServiceException("oss存储类型不支持！！！");
        }
        FileStorageHandler bean = (FileStorageHandler) SpringUtils.getBean(storageType + "FileStorageHandler");
        return bean.uploadFile(file, ossConfig);

    }


    /**
     * 获取oss配置
     *
     * @return SysOss
     */
    public SysOss getOssConfig() {
        List<SysOss> list = sysOssService.openList();
        if (CollectionUtils.isEmpty(list)) {
            throw new ServiceException("oss未配置或未启用");
        }
        return list.get(0);
    }


    @Override
    public String uploadFile(MultipartFile file) {
        String uploadUrl = null;
        SysOss ossConfig = getOssConfig();
        //获取阿里云存储相关常量
        String endPoint = ossConfig.getEndpoint();
        String accessKeyId = ossConfig.getAccessKey();
        String accessKeySecret = ossConfig.getSecretKey();
        String bucketName = ossConfig.getBucketName();

        try {
            //判断oss实例是否存在，如果不存在则创建，如果存在则获取
            OSSClient ossClient = new OSSClient(endPoint, accessKeyId, accessKeySecret);
            if (!ossClient.doesBucketExist(bucketName)) {
                //创建bucket
                ossClient.createBucket(bucketName);
                //设置oss实例的访问权限：公共读
                ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            }

            //获取上传文件流
            InputStream inputStream = file.getInputStream();

            //获取文件名称
            String fileName = StringUtils.isNotEmpty(file.getOriginalFilename()) ? file.getOriginalFilename() : file.getName();
            //在文件名称里面添加随机唯一的值
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            //把文件按照日期进行分类，构建日期路径: xpu-repair/2021/04/14
            String datePath = new DateTime().toString("yyyy/MM/dd");
            //拼接
            fileName = datePath + "/" + uuid + fileName;
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType("text/html");
            //调用oss方法实现上传
            ossClient.putObject(bucketName, fileName, inputStream, metadata);
            //关闭ossClient
            ossClient.shutdown();
            //需要把上传到阿里云oss路径手动拼接出来
            uploadUrl = "https://" + bucketName + "." + endPoint + "/" + fileName;
            log.info("阿里云oss图片地址:{}", uploadUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return uploadUrl;
    }


}
